/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later
 * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
 */
package org.hibernate.query.sqm.function;

import org.hibernate.query.ReturnableType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.tree.SqmTypedNode;

import java.util.List;

/**
 * Acts as a wrapper to another {@link SqmFunctionDescriptor}, rendering the
 * standard JDBC escape sequence {@code {fn f(x, y)}} around the invocation
 * syntax generated by its delegate.
 *
 * @author Steve Ebersole
 * @author Gavin King
 */
public class JdbcEscapeFunctionDescriptor
		extends AbstractSqmFunctionDescriptor {
	private final SqmFunctionDescriptor wrapped;

	public JdbcEscapeFunctionDescriptor(String name, SqmFunctionDescriptor wrapped) {
		super(name);
		this.wrapped = wrapped;
	}

	@Override
	protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
			List<? extends SqmTypedNode<?>> arguments,
			ReturnableType<T> impliedResultType,
			QueryEngine queryEngine) {

		final SelfRenderingSqmFunction<T> delegate =
				wrapped.generateSqmExpression(
						arguments,
						impliedResultType,
						queryEngine
				);

		return new SelfRenderingSqmFunction<>(
				JdbcEscapeFunctionDescriptor.this,
				(sqlAppender, sqlAstArguments, returnType, walker) -> {
					sqlAppender.appendSql("{fn ");
					delegate.getFunctionRenderer()
							.render( sqlAppender, sqlAstArguments, returnType, walker);
					sqlAppender.appendSql("}");
				},
				arguments,
				impliedResultType,
				getArgumentsValidator(),
				getReturnTypeResolver(),
				queryEngine.getCriteriaBuilder(),
				getName());
	}
}
